//
//  DGGNetSign.m
//  DGGCommonSDK
//
//  Created by mac on 2020/4/22.
//

#import "DGGNetSign.h"
#import "NSString+Extension.h"

#if (!defined(DEBUG))
#define NSLog(...)
#endif

static NSString *_sysCode;
static NSString *_secret;
@implementation DGGNetSign

+ (NSDictionary *)signGetRequestWithParams:(NSDictionary *)requestParams requestUrl:(NSString * _Nonnull __autoreleasing *)requsetUrl sysCode:(NSString *)sysCode secret:(NSString *)secret {
    _sysCode = sysCode;
    _secret = secret;
    if(requestParams){
        NSString *requestParamsStr = [self signWithParams:requestParams];
        if(requestParamsStr){
            requestParamsStr = [requestParamsStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        }
        if(*requsetUrl && [*requsetUrl rangeOfString:@"?"].location != NSNotFound){
            //已经有拼接字符串，直接拼在后面
            *requsetUrl = [*requsetUrl stringByAppendingFormat:@"&%@",requestParamsStr];
        }else{
            *requsetUrl = [*requsetUrl stringByAppendingFormat:@"?%@",requestParamsStr];
        }
    }
    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];
    NSString *timeSp = [self getRequestDateStr:date];
    NSLog(@"请求时间：%@",timeSp);
    NSString *nonce = [self getRequestNonceStr:date];
    NSLog(@"请求ID：%@",nonce);
    NSMutableDictionary *tempSign = [NSMutableDictionary dictionary];
    [tempSign setValue:[self getSign:*requsetUrl timeSp:timeSp noce:nonce] forKey:@"sign"];
    [tempSign setValue:timeSp forKey:@"time"];
    [tempSign setValue:nonce forKey:@"nonce"];
    return [tempSign copy];
}

+ (NSDictionary *)signPostRequestWithParams:(NSDictionary *)params sysCode:(NSString *)sysCode secret:(NSString *)secret {
    _sysCode = sysCode;
    _secret = secret;
    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];
    NSString *timeSp = [self getRequestDateStr:date];
    NSLog(@"请求时间：%@",timeSp);
    NSString *nonce = [self getRequestNonceStr:date];
    NSLog(@"请求ID：%@",nonce);
    NSMutableDictionary *tempSign = [NSMutableDictionary dictionary];
    [tempSign setValue:[self postSign:params timeSp:timeSp noce:nonce] forKey:@"sign"];
    [tempSign setValue:timeSp forKey:@"time"];
    [tempSign setValue:nonce forKey:@"nonce"];
    return [tempSign copy];
}

+ (NSString *)signWithParams:(NSDictionary *)params{
    NSArray *keyArray = params.allKeys;
    NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch|NSNumericSearch|NSWidthInsensitiveSearch|NSForcedOrderingSearch;
    NSComparator sort = ^(NSString *obj1,NSString *obj2){
        NSRange range =NSMakeRange(0,obj1.length);
        return [obj1 compare:obj2 options:comparisonOptions range:range];
    };
    NSLog(@"排序前：%@", keyArray);
    keyArray = [keyArray sortedArrayUsingComparator:sort];
    NSLog(@"排序后：%@", keyArray);
    NSMutableString *resultStr = [NSMutableString stringWithString:@""];
    NSInteger index = 0;
    for (NSString *key in keyArray) {
        NSString *value = params[key];
        //空值、空串不参与验签计算
        if(value && ![value isEqualToString:@""]){
            if(index > 0){
                [resultStr appendString:@"&"];
            }
            [resultStr appendFormat:@"%@=%@",key,value];
            index++;
        }
    }
    return resultStr;
}

+ (NSString *)getRequestDateStr:(NSDate *)date{
    NSTimeInterval time = [date timeIntervalSince1970] * 1000;// *1000 是精确到毫秒，不乘就是精确到秒
    NSString *timeSp = [NSString stringWithFormat:@"%.0f", time];
    return timeSp;
}

+ (NSString *)getRequestNonceStr:(NSDate *)date{
    NSString *result = @"";
    int num = (arc4random() % 10000000);
    NSString *randomNumber = [NSString stringWithFormat:@"%.4d", num];
    NSDateFormatter  *dateformatter=[[NSDateFormatter alloc] init];
    [dateformatter setDateFormat:@"yyyyMMddHHmmssSSS"];
    NSString *timeStr = [dateformatter stringFromDate:date];
    timeStr = [timeStr stringByAppendingString:randomNumber];
    result = timeStr;
    return result;
}

+ (NSString *)getSign:(NSString *)urlStr timeSp:(NSString *)timeSp noce:(NSString*)nonce{
    NSDictionary *requestParam = [self requestParamsWithURL:urlStr];
    
   
    NSString *requestStr = @"";
    if(requestParam){
        requestStr = [self signWithParams:requestParam];
        if(requestStr){
            requestStr = [requestStr stringByRemovingPercentEncoding];
        }
    }
    NSMutableDictionary *signParams = @{}.mutableCopy;
    [signParams setValue:nonce forKey:@"nonce"];
    [signParams setValue:timeSp forKey:@"time"];
    [signParams setValue:requestStr forKey:@"data"];
    
    NSString *handleSignStr = [self signWithParams:signParams];
    NSString *signStr = [self createSign:handleSignStr];
    return signStr;
}

#pragma mark - POST验签
+ (NSString *)postSign:(NSDictionary *)requestParams timeSp:(NSString *)timeSp noce:(NSString*)nonce{
    NSString *requestStr = @"";
    if(requestParams){
        NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestParams options:(NSJSONWritingPrettyPrinted) error:nil];
        requestStr = [[NSString alloc] initWithData:requestData encoding:NSUTF8StringEncoding];
        requestStr = [requestStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
        requestStr = [requestStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    NSMutableDictionary *signParams = @{}.mutableCopy;
    [signParams setValue:nonce forKey:@"nonce"];
    [signParams setValue:timeSp forKey:@"time"];
    [signParams setValue:requestStr forKey:@"data"];
    NSString *paramStr = [self signWithParams:signParams];
    NSString *signStr = [self createSign:paramStr];
    return signStr;
}

+ (NSMutableDictionary *)requestParamsWithURL:(NSString *)requestURL{
    NSMutableDictionary *resultDC = @{}.mutableCopy;
    if(requestURL && [requestURL rangeOfString:@"?"].location != NSNotFound){
        NSString *paramsStr = [[requestURL componentsSeparatedByString:@"?"] lastObject];
        NSArray *paramsArray = [paramsStr componentsSeparatedByString:@"&"];
        for (NSString *param in paramsArray) {
            if(param && ![param isEqualToString:@""]){
                NSArray *keyValues = [param componentsSeparatedByString:@"="];
                if(keyValues.count > 0){
                    NSString *key = [keyValues firstObject];
                    NSString *value = @"";
                    if(keyValues.count > 1){
                        value = [keyValues lastObject];
                    }
                    [resultDC setValue:value forKey:key];
                }
            }
        }
    }
    return resultDC;
}

+ (NSString *)createSign:(NSString *)resultStr{
    NSString *sortASCIIString = [self addCodeStr:resultStr];
    //MD5加密,结果转换为大写字符
    NSString *sign = [[NSString md5:sortASCIIString] uppercaseString];
    NSLog(@"签名前：%@\n签名后：%@", sortASCIIString, sign);
    return sign;
}

+ (NSString *)addCodeStr:(NSString *)sortString{
    NSMutableString *resultStr = [sortString mutableCopy];
    if(resultStr && sortString.length > 0){
        [resultStr appendString:@"&"];
    }
    [resultStr appendFormat:@"sysCode=%@", _sysCode];
    [resultStr appendFormat:@"&secret=%@", _secret];
    //过滤表情包
    NSString *filteredStr = [self filterEmoji:resultStr];
    return filteredStr;
//    return resultStr;
}

+ (NSString *)filterEmoji:(NSString *)source {
    //去除表情
    NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFFF\\u0000\\u0009\\u000A\\u000D]" options:NSRegularExpressionCaseInsensitive error:nil];
    
    NSString* result = [expression stringByReplacingMatchesInString:source options:0 range:NSMakeRange(0, source.length) withTemplate:@""];
    return result;
}

@end
